package api

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"

	"github.com/gorilla/mux"
	"github.com/linclaus/stock/pkg/cache"
	"github.com/linclaus/stock/pkg/db"
	"github.com/linclaus/stock/pkg/grafana"
	"github.com/linclaus/stock/pkg/model"
)

func (s *Server) CreateDashboard(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Printf("Failed to read payload: %s\n", err)
		http.Error(w, fmt.Sprintf("Failed to read payload: %s", err), http.StatusBadRequest)
		return
	}

	dr := &model.DashboardRequest{}
	err = json.Unmarshal(body, dr)

	if err := grafana.CreateCustomDashboard(dr.FolderName, dr.DashboardName, dr.Expression, dr.PannelType); err != nil {
		fmt.Printf("Create dashboard:%s failed for reason:%s\n", dr.DashboardName, err)
		http.Error(w, fmt.Sprintf("Create dashboard:%s failed\n", dr.DashboardName), http.StatusBadRequest)
	}
}

func (s *Server) DeleteDashboard(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Printf("Failed to read payload: %s\n", err)
		http.Error(w, fmt.Sprintf("Failed to read payload: %s", err), http.StatusBadRequest)
		return
	}

	dr := &model.DashboardRequest{}
	err = json.Unmarshal(body, dr)

	if err := grafana.RemoveDashboard(dr.DashboardName); err != nil {
		fmt.Printf("Delete dashboard:%s failed for reason:%s\n", dr.DashboardName, err)
		http.Error(w, fmt.Sprintf("Delete dashboard:%s failed\n", dr.DashboardName), http.StatusBadRequest)
	}
}

func (s *Server) GetDashboardByCode(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	stock, _ := cache.StockMap.Get(vars["code"])
	board := cache.BoardMap[fmt.Sprintf("%s:%s", stock.Code, stock.Name)]
	b, _ := json.Marshal(board)
	w.Write([]byte(string(b)))
}

func (s *Server) SaveDashboardImageByCode(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	stock, _ := cache.StockMap.Get(vars["code"])
	board := cache.BoardMap[fmt.Sprintf("%s:%s", stock.Code, stock.Name)]
	cache.GrafanaRendererChan <- board
	b, _ := json.Marshal(board)
	w.Write([]byte(string(b)))
}

func (s *Server) GetStockImage(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	si, _ := db.StockInfoMgr.GetStockInfoByNameOrCode(vars["code"])
	des := STOCK_FILE_PATH + fmt.Sprintf("png/%s:%s.png", si.Code, si.Name)
	desStat, err := os.Stat(des)
	if err != nil {
		log.Println("Read File Error:", err.Error())
		log.Println("File Not Exit", des)
		http.NotFoundHandler().ServeHTTP(w, r)
	} else if desStat.IsDir() {
		log.Println("File Is Dir", des)
		http.NotFoundHandler().ServeHTTP(w, r)
	} else {
		fileData, err := ioutil.ReadFile(des)
		if err != nil {
			log.Println("Read File Err:", err.Error())
		} else {
			log.Println("Send File:", des)
			w.Header().Set("Content-Type", "image/png")
			w.Write(fileData)
		}
	}

}
